using System;
using System.Text;
using Castle.ActiveRecord;
using System.Collections.Generic;
using NHibernate.Expression;
using Castle.ActiveRecord.Queries;

namespace Old.KenEgozi.Com.Domain.Blog
{
	[Import(typeof(ArchiveEntry), "ArchiveEntry")]
	[Import(typeof(TagCloudEntry), "TagCloudEntry")]
	[ActiveRecord("Blog_Blogs")]
	public class Blog : BlogBase<Blog>
	{
		private string _name;
		private string _title;
		private string _url;
		private IList<Post> _posts = new List<Post>();
		private IList<Author> _authors = new List<Author>();

		[Property]
		public string Name
		{
			get { return _name; }
			set { _name = value; }
		}

		[Property]
		public string Title
		{
			get { return _title; }
			set { _title = value; }
		}

		[Property]
		public string Url
		{
			get { return _url; }
			set { _url = value; }
		}

		[HasMany(Lazy = true, Access = PropertyAccess.NosetterCamelcaseUnderscore, Cascade = ManyRelationCascadeEnum.All)]
		public virtual IList<Post> Posts
		{
			get { return _posts; }
		}

		[HasAndBelongsToMany(
			Lazy = true,
			Table = "Blog_BlogAuthors",
			ColumnKey = "BlogId",
			ColumnRef = "AuthorId",
			Access = PropertyAccess.NosetterCamelcaseUnderscore)]
		public virtual IList<Author> Authors
		{
			get { return _authors; }
		}

		public Post FindPost(int year, int month, int day, string title)
		{
			string permalink = string.Format(
				"{0}/{1:0000}/{2:00}/{3:00}/{4}",
				Name, year, month, day, title);
			return Post.FindOne(Expression.InsensitiveLike("Permalink", permalink));
		}

		public static Blog FindByName(string blogName)
		{
			return FindOne(Expression.InsensitiveLike("Name", blogName));
		}

		public Post[] FindRecentPosts()
		{
			return Post.FindRecent(this);
		}
		public Post[] FindRecentPosts(int maxPosts)
		{
			return Post.FindRecent(maxPosts, this);
		}
		public Tag[] FindAllTags()
		{
			string hql = @"
				select distinct t, count(p)
				from 
					Tag t inner join
					t.Posts post
				where post.Blog = ?";

			SimpleQuery<object[]> q = new SimpleQuery<object[]>(typeof(Tag), hql, this);
			object[][] items = q.Execute();
			foreach (object[] o in items)
				Console.WriteLine("{0} | {1}", o[0], o[1]);
			return new Tag[0];
		}

		public ArchiveEntry[] GetArchiveEntries()
		{
			SimpleQuery<ArchiveEntry> q = new SimpleQuery<ArchiveEntry>(typeof(ActiveRecordBase), @"
                select new ArchiveEntry(year(p.CreationDate), month(p.CreationDate), count(p.Id)) 
                from Post p
				where p.Blog = ?
                order by year(p.CreationDate) desc, month(p.CreationDate) desc
                group by year(p.CreationDate), month(p.CreationDate)", this);
			return q.Execute();
		}
		public TagCloudEntry[] GetTagCloud()
		{
			SimpleQuery<TagCloudEntry> q = new SimpleQuery<TagCloudEntry>(typeof(ActiveRecordBase), @"
                select new TagCloudEntry(t.Name, t.UrlFriendlyName, count(p)) 
                from 
					Tag t inner join
					t.Posts p
				where p.Blog = ?
                order by t.Name
                group by t.Name, t.UrlFriendlyName", this);
			return q.Execute();
		}

		/// <summary>
		/// Get the blog's blogroll from DB
		/// TODO: Should be adapted to a multiblog enviroment
		/// </summary>
		/// <returns></returns>
		public static BlogRollEntry[] FindBlogRoll()
		{
			return BlogRollEntry.FindAll(Order.Asc("Title"));
		}
	}
}

struct TagInCloud
{
	int tagId;
	int count;

}